package UI;

import DataStructure.Model;
import OBJ.MaterialUpdateRequest;
import OBJ.ObjModelLoader;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ModelEditor extends JFrame {
    private Model currentModel;                                             // 当前模型
    private Map<String, MaterialPanel> materialPanels = new HashMap<>();    // 材质面板
    private JPanel materialPanelContainer;                                  // 材质面板容器
    private static volatile Thread workTread = null;
    private static volatile Thread voxelTread = null ;// 工作线程
    private ConcurrentLinkedQueue<MaterialUpdateRequest> materialQueue;     // 材质更新队列
    private String nameOBJ;
    private int heightLimit;

    //private File defaultDir=new File(System.getProperty("user.home"), "Desktop");   // 默认目录
    private File defaultDir = new File("E:\\game\\NoFleshWithinChest-Beta\\建模\\爱莉希雅律者2.0_by_神帝宇_1e1281846d381fb4553fcc5b5a6cdfbf\\爱莉希雅律者2.0");   // 默认目录
    public ModelEditor(ConcurrentLinkedQueue<MaterialUpdateRequest> materialQueue) {
        this.materialQueue = materialQueue;
        initUI();
    }

    private void initUI() {
        setTitle("3D Model Editor");
        setSize(400, 800); // 缩窄窗口宽度
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // 主布局使用垂直排列
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));

        // 模型加载按钮
        JButton loadModelBtn = new JButton("Load Model");
        loadModelBtn.addActionListener(e -> loadModel());
        mainPanel.add(loadModelBtn);

        //限高
        JTextField voxelHeight = new JTextField(16);
        mainPanel.add(voxelHeight);

        //体素化加载按钮
        JButton loadVoxelBtn = new JButton(("load Voxel"));
        loadVoxelBtn.addActionListener(e->loadVoxel(voxelHeight));
        mainPanel.add(loadVoxelBtn);

        // 材质面板容器
        materialPanelContainer = new JPanel();
        materialPanelContainer.setLayout(new BoxLayout(materialPanelContainer, BoxLayout.Y_AXIS));
        JScrollPane scrollPane = new JScrollPane(materialPanelContainer);
        mainPanel.add(scrollPane);

        add(mainPanel);
    }

    // 加载模型
    private void loadModel() {
        //模型选择
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setCurrentDirectory(defaultDir);
        fileChooser.setFileFilter(new FileNameExtensionFilter("OBJ Files", "obj"));
        if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            try {
                String pathOBJ = fileChooser.getSelectedFile().getPath();
                defaultDir = fileChooser.getSelectedFile().getParentFile();
                nameOBJ = pathOBJ.replaceAll("(.*)\\\\([^\\\\]*){1}\\.obj", "$2");
                currentModel = ObjModelLoader.loadModel(defaultDir +"\\",nameOBJ);
                //更新材质面板
                updateMaterialPanels();
                //启动工作线程
                if(workTread!=null)
                {
                    workTread.interrupt();
                    try {
                        workTread.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                workTread  = new Thread(() -> {
                    try {
                        ModelWindow window = new ModelWindow(1200, 800,defaultDir.getPath(),nameOBJ,materialQueue);
                        window.run();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });
                workTread.start();

            } catch (IOException ex) {
                JOptionPane.showMessageDialog(this, "Error loading model: " + ex.getMessage());
            }
        }
    }
    private void loadVoxel(JTextField voxelHeight){

            heightLimit =  Integer.parseInt(voxelHeight.getText());
            if(heightLimit == 0) return;
        //启动工作线程
        if(voxelTread!=null)
        {
            voxelTread.interrupt();
            try {
                voxelTread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        voxelTread  = new Thread(() -> {
            try {
                VoxelWindow window = new VoxelWindow(1200, 800,defaultDir.getPath(),nameOBJ,materialQueue,heightLimit);
                window.run();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        voxelTread.start();

    }
    // 更新材质
    public void updateMaterial(MaterialUpdateRequest request) {
        for(Model.Material material : currentModel.materials) {
            if(material.name.equals(request.name)) {
                material.diffuseColor.set(request.diffuseColor);
                material.path = request.path;
                break;
            }
        }

    }
    // 更新材质面板
    private void updateMaterialPanels() throws IOException {
        materialPanelContainer.removeAll();
        materialPanels.clear();

        for (Model.Material material : currentModel.materials) {
            MaterialPanel panel = new MaterialPanel(material);
            materialPanels.put(material.name, panel);
            materialPanelContainer.add(panel);
            materialPanelContainer.add(Box.createVerticalStrut(10));
        }
        materialPanelContainer.revalidate();
        materialPanelContainer.repaint();
    }



    // 材质面板
    class MaterialPanel extends JPanel {
        private final Model.Material material;
        private JLabel colorPreview;
        private JTextField texturePathField;

        public MaterialPanel(Model.Material material) throws IOException {
            this.material = material;
            initUI();
        }

        private void initUI() throws IOException {
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            setBorder(BorderFactory.createTitledBorder(material.name));

            // 颜色选择
            JPanel colorPanel = new JPanel();
            colorPreview = new JLabel();
            colorPreview.setOpaque(true);
            colorPreview.setBackground(new Color(
                    material.diffuseColor.x,
                    material.diffuseColor.y,
                    material.diffuseColor.z
            ));
            colorPreview.setPreferredSize(new Dimension(50, 20));

            JButton colorBtn = new JButton("Choose Color");
            colorBtn.addActionListener(e -> {
                try {
                    chooseColor();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            });

            colorPanel.add(new JLabel("Diffuse Color:"));
            colorPanel.add(colorPreview);
            colorPanel.add(colorBtn);

            // 贴图选择
            JPanel texturePanel = new JPanel();
            texturePathField = new JTextField(20);
            texturePathField.setEditable(false);


            JButton textureBtn = new JButton("Load Texture");
            textureBtn.addActionListener(e -> {
                try {
                    loadTexture();
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            });

            texturePanel.add(new JLabel("Texture:"));
            texturePanel.add(texturePathField);
            texturePanel.add(textureBtn);
            add(colorPanel);
            add(texturePanel);

            //贴图显示
            if (material.path != null) {
                BufferedImage original = ImageIO.read(new File(material.path));
                JLabel texturePreview = new JLabel(new ImageIcon(picturScale(original)));
                texturePanel.add(texturePreview);
            }
        }
        //选择颜色事件
        private void chooseColor() throws IOException {
            MaterialUpdateRequest request = new MaterialUpdateRequest();
            request.name = material.name;
            Color newColor = JColorChooser.showDialog(
                    ModelEditor.this,
                    "Choose Diffuse Color",
                    colorPreview.getBackground()
            );

            if (newColor != null) {
                colorPreview.setBackground(newColor);
                request.diffuseColor.set(
                        newColor.getRed() / 255f,
                        newColor.getGreen() / 255f,
                        newColor.getBlue() / 255f
                );
            }
            //提交更新并更新自己
            updateMaterial(request);
            materialQueue.offer(request);
            updateMaterialPanels();
        }
        //加载贴图事件
        private void loadTexture() throws IOException {
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setCurrentDirectory(defaultDir);
            fileChooser.setFileFilter(new FileNameExtensionFilter("Image Files", "jpg", "png", "bmp"));
            MaterialUpdateRequest request = new MaterialUpdateRequest();
            request.name = material.name;
            if (fileChooser.showOpenDialog(ModelEditor.this) == JFileChooser.APPROVE_OPTION) {
                String path = fileChooser.getSelectedFile().getPath();
                request.path = path;
                //提交更新并更新自己
                updateMaterial(request);
                materialQueue.offer(request);
                updateMaterialPanels();
            }

        }

        //图片缩放
        private BufferedImage  picturScale(BufferedImage originalImage) {
            // 计算缩放比例
            int originalWidth = originalImage.getWidth();
            int originalHeight = originalImage.getHeight();
            double ratio = Math.min(100.0 / originalWidth, 100.0 / originalHeight);
            int scaledWidth = (int) (originalWidth * ratio);
            int scaledHeight = (int) (originalHeight * ratio);

            // 高质量缩放（比getScaledInstance更可控）
            BufferedImage scaledImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = scaledImage.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
            g2d.dispose();

            JLabel texturePreview = new JLabel(new ImageIcon(scaledImage));
            return scaledImage;
        }
    }


}
